import SEO from "../components/SEO";

<SEO
  title="PseudoBox"
  description="PseudoBox component provides props to style common CSS pseudo selectors."
/>

# PseudoBox

This component is inspired by
[Tailwind CSS](https://tailwindcss.com/docs/pseudo-class-variants) Pseudo-Class
variants.

PseudoBox composes [Box](/box) component and provides props to style common CSS
pseudo selectors.

Styling elements on hover, focus, and more can be accomplished by prefixing `_`
with the appropriate pseudo-selector.

For example, to style `&:hover`, use the `v-bind:_hover="{ /* hover styles here */ }"` prop and pass the style props.
We use the underscore `_` prefix notation to visually separate pseudo style props from
regular style props.

This prop accepts an object of the styles you wish to apply to the element. All styles also have access your theme
object in `$chakraTheme`.

<carbon-ad />

## Import

```js
import { CPseudoBox } from '@chakra-ui/vue'
```

```vue live=true
<c-flex as="form">
  <c-pseudo-box
    as="input"
    placeholder="Your email"
    type="email"
    flex="1"
    py="2"
    px="4"
    rounded="md"
    bg="gray.100"
    border-width="1px"
    :_hover="{ borderColor: 'gray.200', bg: 'gray.200' }"
    :_focus="{
      outline: 'none',
      bg: 'white',
      boxShadow: 'outline',
      borderColor: 'gray.300',
    }"
  />
  <c-pseudo-box
    as="button"
    bg="blue.500"
    py="2"
    px="4"
    ml="3"
    rounded="md"
    font-weight="semibold"
    color="white"
    :_hover="{ bg: 'blue.600' }"
    :_focus="{ boxShadow: 'outline' }"
  >
    Sign Up
  </c-pseudo-box>
</c-flex>
```

The `CPseudoBox` includes first-class support for styling elements on hover, focus,
active, disabled, visited, first-child, last-child, odd-child, even-child,
focus-within, and more.

This allows you to conveniently and declaratively set the pseudo styles of the element using style props.


### Hover

Add the `v-bind:_hover` prop to only apply style props on hover.

```vue live=true
<c-pseudo-box
  as="button"
  color="blue.700"
  font-weight="semibold"
  py="2"
  px="4"
  border-width="1px"
  border-wolor="blue.500"
  rounded="md"
  :_hover="{ bg: 'blue.500', color: 'white' }"
  :_focus="{ shadow: 'outline' }"
>
  Hover me
</c-pseudo-box>
```

### Focus

Add the dynamic `v-bind:_focus` prop to only apply a style on focus.

```vue live=true
<c-pseudoBox
  as="input"
  placeholder="Focus me"
  py="2"
  px="4"
  bg="gray.200"
  color="gray.900"
  border-color="transparent"
  border-width="2px"
  rounded="md"
  :_focus="{ bg: 'white', borderColor: 'blue.400' }"
/>
```


### Active

Add the `v-bind:_active` prop to only apply a style on active.

```vue live=true
<c-pseudo-box
  as="button"
  font-weight="semibold"
  py="2"
  px="4"
  rounded="md"
  color="white"
  bg="blue.500"
  :_active="{ bg: 'blue.700' }"
  :_focus="{ boxShadow: 'outline' }"
>
  Click me
</c-pseudo-box>
```

### Disabled

Add the `v-bind:_disabled` prop to style an element when it is disabled. This style
will apply when the `disabled` or `aria-disabled` attribute of an element is set
to `true`

```vue live=true
<c-stack is-inline>
  <c-pseudo-box
    as="button"
    font-weight="semibold"
    py="2"
    px="4"
    rounded="md"
    color="white"
    bg="blue.500"
    :_active="{ bg: 'blue.700' }"
    :_focus="{ boxShadow: 'outline' }"
  >
    Click me
  </c-pseudo-box>

  <c-pseudo-box
    as="button"
    disabled
    font-weight="semibold"
    py="2"
    px="4"
    rounded="md"
    color="white"
    bg="blue.500"
    :_active="{ bg: 'blue.700' }"
    :_focus="{ boxShadow: 'outline' }"
    :_disabled="{ opacity: 0.6 }"
  >
    Click me
  </c-pseudo-box>
</c-stack>
```

### Visited

Add the `v-bind:_visited` props to style a link that has been visited.

```vue live=true
<c-stack is-inline>
  <c-pseudo-box
    as="a"
    href="/radio"
    color="blue.600"
    text-decoration="underline"
    font-weight="semibold"
  >
    Unvisited Link
  </c-pseudo-box>
  <c-pseudo-box
    as="a"
    href="/pseudobox"
    color="blue.600"
    text-decoration="underline"
    fontWeight="semibold"
    v-bind:_visited="{ color: 'indigo.600' }"
  >
    Visited Link
  </c-pseudo-box>
</c-stack>
```

### First Child

Add the `v-bind:_first` prop to style an element when it is the first-child of its
parent. This is mostly useful when elements are being generated in some kind of
loop.


```vue live=true
<c-box border-width="1px" rounded="md">
  <c-pseudoBox
    v-for="item in ['One', 'Two', 'Three']"
    :key="item"
    px="4"
    py="2"
    borderTopWidth="1px"
    :_first="{ borderTopWidth: 0 }"
  >
    {{ item }}
  </c-pseudoBox>
</c-box>
```

### Last Child

Add the `v-bind:_last` prop to style an element when it is the last-child of its
parent. This is mostly useful when elements are being generated in some kind of
loop.

```vue live=true
<c-box border-width="1px" rounded="md">
  <c-pseudoBox
    v-for="item in ['One', 'Two', 'Three']"
    :key="item"
    px="4"
    py="2"
    borderBottomWidth="1px"
    :_last="{ borderBottomWidth: 0 }"
  >
    {{ item }}
  </c-pseudoBox>
</c-box>
```


### Odd Child

Add the `v-bind:_odd` prop to style an element when it is the odd-child of its parent.
This is mostly useful when elements are being generated in some kind of loop.

```vue live=true
<c-box border-width="1px" rounded="md">
  <c-pseudoBox
    v-for="item in ['One', 'Two', 'Three']"
    :key="item"
    px="4"
    py="2"
    bg="white"
    borderBottomWidth="1px"
    :_odd="{ bg: 'gray.100' }"
  >
    {{ item }}
  </c-pseudoBox>
</c-box>
```

### Even Child

Add the `v-bind:_even` prop to style an element when it is the even-child of its
parent. This is mostly useful when elements are being generated in some kind of
loop.

```vue live=true
<c-box border-width="1px" rounded="md">
  <c-pseudoBox
    v-for="item in ['One', 'Two', 'Three']"
    :key="item"
    px="4"
    py="2"
    bg="white"
    borderBottomWidth="1px"
    :_even="{ bg: 'gray.100' }"
  >
    {{ item }}
  </c-pseudoBox>
</c-box>
```

### Group Hover

If you need to style a child element when hovering over a specific parent
element, add the `role="group"` attribute to the parent element, then you can
use `:_groupHover` prop to style the child element.

```vue live=true
<c-pseudo-box
  role="group"
  max-w="sm"
  overflow="hidden"
  rounded="md"
  p="5"
  cursor="pointer"
  bg="white"
  box-shadow="md"
  :_hover="{ bg: 'blue.500' }"
>
  <c-pseudo-box
    font-weight="semibold"
    font-size="lg"
    mb="1"
    color="gray.900"
    :_groupHover="{ color: 'white' }"
  >
    New Project
  </c-pseudo-box>
  <c-pseudo-box color="gray.700" :mb="2" :_groupHover="{ color: 'white' }">
    Create a new project from a variety of starting templates.
  </c-pseudo-box>
</c-pseudo-box>
```


## Selectors and Props

PseudoBox can be used to style any interactive component. You can apply styles
to the following selectors. The selectors are also ARIA-friendly to help you
naturally use `aria` attributes for better accessibility.

All PseudoBox props can use the style props.
[Learn more about Style props](/style-props)

| Selector                               | Prop           |
| -------------------------------------- | -------------- |
| `&:hover`                              | `_hover`       |
| `&:active`                             | `_active`      |
| `&:focus`                              | `_focus`       |
| `&:before`                             | `_before`      |
| `&:after`                              | `_after`       |
| `&::placeholder`                       | `_placeholder` |
| `&:first-of-type`                      | `_first`       |
| `&:last-of-type`                       | `_last`        |
| `[role=group]:hover &`                 | `_groupHover`  |
| `&:disabled`, `[aria-disabled=true]`   | `_disabled`    |
| `&[readonly]`, `&[aria-readonly=true]` | `_readonly`    |
| `&[aria-checked=true]`                 | `_checked`     |
| `&[aria-selected=true]`                | `_selected`    |
| `&[aria-expanded=true]`                | `_expanded`    |
| `&[aria-invalid=true]`                 | `_invalid`     |
| `&[aria-pressed=true]`                 | `_pressed`     |
| `&[aria-invalid=true]`                 | `_invalid`     |
| `&[aria-grabbed=true]`                 | `_grabbed`     |
